'''
Created on Jul 9, 2009

@author: xin
@author: Mikael Rousson
'''
import numpy
import build_lpyr
import lpyram_extract_nbands
import wneigh_extract
import find_significant_coeff
import find_significant_lf_patches

def lp_patch_index(im, ht, blur_filt, interp_filt, kepercent,
                   DIMS, DIML, lvlist, LF_DIMS):
    """ Builds patches of 18-components with 1/64 of coefficients in the first 
    2 sub-bands of Laplacian pyramid. The patch structure is determined by 
    variables dims and diml. DIM is a cell array that contains the number of 
    neighbors in each sub-band for each color channel (ex: {[5 1] [5 1] [5 1]} 
    means that a neighborhood kind [5 1] has to be extracted from each channel 
    DIML contains information about which sub-bands have to be considered in 
    building a patch (ex: {[0 1][0 1][0 1]} means [0 1] for all channels) LF
    determines the patch to be extracted from the low frequency sub-band of all 
    color channels; e.g.: LF = 9 means a 3x3 spatial neighborhood if LF = 0 low 
    frequency sub-band is not considered.
    """
    nch = im.shape[2]
    patches = {}
    significant = {}
    for ch in range(nch):
        a = DIMS
        b = DIML
        pyr, pind = build_lpyr.build_lpyr(im[:, :, ch], ht, blur_filt, interp_filt)
        
        ct = 1
       
        for l in range(len(lvlist)):           
            scale = lvlist[l]
            if scale == ht - 1:
                for i in range (size(DIMS, 2)):
                    a[i, :] = a[i, :](where(b[i] == 0)[0])
                b = array([0, 0, 0])       
                
            # group required subbands
            X, dind = \
            lpyram_extract_nbands.lpyram_extract_nbands(pyr, pind, scale, b[ch]) 
            Y = numpy.single(wneigh_extract.wneigh_extract(X, a[ch][dind]))
            Y = Y.T
            if (ch == 0):
                significant[ct] = \
                find_significant_coeff.find_significant_coeff(Y, kepercent[l])
                patches[ct] = numpy.ndarray(shape=(len(significant[ct]), 1))

            Y = Y[significant[ct], :]
            if (ch == 0):
                patches[ct] = Y
            else :
                patches[ct] = numpy.hstack((patches[ct], Y))
            ct = ct + 1
            
        if (LF_DIMS != 0):
                scale = ht
                # group required subbands
                X, dind = lpyram_extract_nbands.\
                lpyram_extract_nbands(pyr, pind, scale, 0)
                Y = numpy.single (wneigh_extract.wneigh_extract(X, numpy.array([LF_DIMS])))
                if (ch == 0):
                    significant_lf = find_significant_lf_patches.\
                    find_significant_lf_patches(Y, 1)
                    patches[ct] = numpy.ndarray(shape=(len(significant_lf), 1))
                Y = Y.T
                Y = Y [significant_lf, :]
                if (ch == 0):
                     patches[ct ] = Y
                else :
                    patches[ct] = numpy.hstack((patches[ct], Y))
    return patches

